/*
 * httpnetworkcontext.cpp
 *
 *  Created on: Sep 20, 2011
 *      Author: anonovermind <anonovermind@gmail.com>
 */

#include "../include/httpnetworkcontext.h"
#include <sstream>
#include <vector>
#include <boost/algorithm/string.hpp>
#include "exceptions.h"

namespace Wishmaster2
{
namespace Network
{

HttpNetworkContext::HttpNetworkContext()
{
}

HttpNetworkContext::~HttpNetworkContext()
{
}

void HttpNetworkContext::serialize(std::ostream& stream)
{
	for(auto domainIterator = m_cookies.begin(); domainIterator != m_cookies.end(); ++domainIterator)
	{
		stream << domainIterator->first << std::endl;
		stream << domainIterator->second.size() << std::endl;
		for(auto it = domainIterator->second.begin(); it != domainIterator->second.end(); ++it)
		{
			stream << it->first << "=" << it->second << std::endl;
		}
	}
}

void HttpNetworkContext::deserialize(std::istream& stream)
{
	while(!stream.eof())
	{
		std::string domain;
		int num;
		stream >> domain;
		if(domain.empty())
			return;
		stream >> num;
		for(int i = 0; i < num; i++)
		{
			std::string cookieStr;
			stream >> cookieStr;
			std::vector<std::string> result;
			boost::split(result, cookieStr, boost::is_any_of("="));
			if(result.size() != 2)
				throw DeserializationException(cookieStr);
			addCookie(domain, result[0], result[1]);
		}
	}
}

void HttpNetworkContext::setParameters(const std::string& str)
{
	std::vector<std::string> result;
	boost::split(result, str, boost::is_any_of(":"));

	std::string domain = result[0];

	std::vector<std::string> cookies;
	boost::split(cookies, result[1], boost::is_any_of(";"));

	for(auto s : cookies)
	{
		if(!s.empty())
		{
			std::vector<std::string> cookie;
			boost::split(cookie, s, boost::is_any_of("="));
			boost::trim(cookie[0]);
			boost::trim(cookie[1]);
			if((cookie[0].empty()) || (cookie[1].empty()) || (cookie.size() != 2))
				throw DeserializationException(std::string("HttpNetworkContext: invalid cookie string: ") + str);
			addCookie(domain, cookie[0], cookie[1]);
		}
	}
}

void HttpNetworkContext::addCookie(const std::string& domain, const std::string& name, const std::string& value)
{
	m_cookies[domain][name] = value;
}

std::string HttpNetworkContext::cookieStringForDomain(const std::string& domain)
{
	auto domainNode = m_cookies.find(domain);
	if(domainNode == m_cookies.end())
		return std::string();

	std::ostringstream stream;
	for(auto it = domainNode->second.begin(); it != domainNode->second.end(); ++it)
	{
		stream << it->first << "=" << it->second << ";";
	}
	return stream.str();
}

} /* namespace Network */
} /* namespace Wishmaster2 */
